home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 4 / Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso / Development / Source / Telnet 2.6.1d1 4⁄26⁄94 Folder / source / vs / vsem.c < prev    next >
Text File  |  1994-02-20  |  25KB  |  893 lines

  1. /*
  2.  *
  3.  *      Virtual Screen Kernel Emulation Routines
  4.  *                      (vsem.c)
  5.  *  
  6.  *   National Center for Supercomputing Applications
  7.  *      by Gaige B. Paulsen
  8.  *
  9.  *    This file contains the private emulation calls for the NCSA
  10.  *  Virtual Screen Kernel.
  11.  *
  12.  *-----------------------------------------------------------------------------------
  13.  *    This also now contains Roland Mansson's code for printer redirection
  14.  *    Thanks for all of the work, Roland!
  15.  *-----------------------------------------------------------------------------------
  16.  *
  17.  *      Version Date    Notes
  18.  *      ------- ------  ---------------------------------------------------
  19.  *      0.01    861102  Initial coding -GBP
  20.  *      0.10    861111  Added/Modified VT emulator -GBP
  21.  *      0.50    861113  First compiled edition -GBP
  22.  *        2.1        871130    NCSA Telnet 2.1 -GBP
  23.  *        2.2     880715    NCSA Telnet 2.2 -GBP
  24.  *        2.6        12/92    Telnet 2.6: Fixed some VS stuff, and added LU changes
  25.  */
  26.  
  27. #ifdef MPW
  28. #pragma segment VS
  29. #endif
  30.  
  31. #include <Printing.h>
  32. #include <string.h>
  33. #include <stdio.h>
  34.  
  35. #include "TelnetHeader.h"                    /* LU - need normcurs definition */
  36. #include "wind.h"
  37. #include "vsdata.h"
  38. #include "vskeys.h"
  39. #include "rsmac.proto.h"
  40. #include "vsintern.proto.h"
  41. #include "vsinterf.proto.h"
  42. #include "translate.proto.h"
  43. #include "debug.h"
  44. #include "maclook.proto.h"
  45. #include "printing.proto.h"
  46. #include "event.proto.h"
  47. #include "menuseg.proto.h"
  48.  
  49. #include "vsem.proto.h"
  50.  
  51. extern THPrint PrRecHandle;        /* LU - our print record handle from menu.c */
  52. extern SysEnvRec theWorld;        /* LU - System Environment record from environ.c */
  53. extern Cursor *theCursors[];
  54. extern long        TempItemsDirID;
  55. extern short    TempItemsVRefNum;
  56. extern WindRec *screens;
  57.  
  58. void    VSunload(void) {}
  59.  
  60. /* LU - this is the start of the main LU changes for doing printer redirection     */
  61. /*     Once again I would like to thank Roland Mansson, of the Lund University 
  62.     Computing Center (Sweden) for all of his work on Telnet.   Not only for the 
  63.     national char support, but also for the printer redirection support, a new 
  64.     version of PrintPages, and everything else.  Thanks a lot, and keep up the
  65.     good work!!!        -SMB                                                    */
  66. /* LU - we have gotten the escape sequence to turn on printer redirection, so do so */ 
  67. void VSprON(void)
  68. {
  69.     char    tmp[100];                /* only for debugging */
  70.     OSErr    sts;
  71.     
  72.     putln ("printer redirection ON");
  73.     VSIw->prredirect = 1;
  74.     VSIw->prbuf = 0x00000000;
  75.     sprintf (VSIw->fname,"NCSA Telnet tempfile #%d",VSIwn);
  76.     c2pstr(VSIw->fname);                                    /* BYU 2.4.18 */
  77.  
  78.     if (sts = HCreate(TempItemsVRefNum, TempItemsDirID, (StringPtr)VSIw->fname, '????', 'TEXT')) {
  79.         if (sts != dupFNErr) {
  80.             SysBeep(1);
  81.             VSIw->prredirect = 0;
  82.             sprintf(tmp,"Create: ERROR %d",sts);
  83.             putln(tmp);
  84.             return;
  85.             }
  86.         }
  87.     if (sts = HOpen(TempItemsVRefNum, TempItemsDirID, (StringPtr)VSIw->fname, fsRdWrPerm, &(VSIw->refNum))) {
  88.         SysBeep(1);
  89.         VSIw->prredirect = 0;
  90.         sprintf(tmp,"FSOpen: ERROR %d",sts);
  91.         putln(tmp);
  92.         HDelete(TempItemsVRefNum, TempItemsDirID, (StringPtr)VSIw->fname);
  93.         return;
  94.         }
  95.     if (SetEOF(VSIw->refNum, 0L)) {
  96.         SysBeep(1);
  97.         VSIw->prredirect = 0;
  98.         putln("VSPRON:SETEOF ERROR");
  99.         HDelete(TempItemsVRefNum, TempItemsDirID, (StringPtr)VSIw->fname);
  100.         return;
  101.         }
  102. }
  103.  
  104.  
  105. /* LU - we just got the escape sequence to turn OFF redirection.  Take what we have
  106.         and dump it to the printer */
  107.         
  108. void VSprOFF(void)
  109. {
  110.     Str255        Title;
  111.     TPrStatus    prStatus;    /* Status record */
  112.     TPPrPort    prPort;        /* the Printer port */
  113.     OSErr        sts;
  114.     GrafPtr        savePort;
  115.     char        tmp[100];    /* only for debugging */
  116.     short        temp;        /* NCSA: SB - the screen # */
  117.     THPrint        PrRecHandle;
  118.     
  119.     putln ("printer redirection OFF");
  120.     if (VSIw->prredirect==0)            /* no redirection started! */
  121.         return;
  122.     VSIw->prredirect = 0;
  123.     GetPort (&savePort);                /* save old port */
  124.  
  125.     PrOpen();
  126.     
  127.     PrRecHandle = PrintSetupRecord();
  128.     
  129.     GetWTitle ((GrafPtr) RSgetwindow(VSIwn),Title);
  130.     SetCursor(theCursors[normcurs]);
  131.     
  132.     if (PrJobDialog(PrRecHandle)) {            /* Cancel the print if FALSE */
  133.         if (sts=PrError()) { sprintf(tmp,"PrJobDialog: ERROR %d",sts); putln(tmp); }
  134.         prPort=PrOpenDoc(PrRecHandle,0L,0L);
  135.         if (sts=PrError()) {
  136.             SysBeep(1);
  137.             sprintf(tmp,"PrOpenDoc: ERROR %d",sts); putln(tmp);
  138.         } else {
  139.             temp = findbyVS(VSIwn);                    /* NCSA: SB */
  140.             if (temp < 0)    {
  141.                 PrClose();                    /* NCSA: SB */
  142.                 DisposeHandle((Handle)PrRecHandle);
  143.                 return;                            /* NCSA: SB */
  144.                 }
  145.             printPages (prPort, PrRecHandle, Title, VSmaxwidth(VSIwn), NULL, VSIw->refNum, 0L,temp);
  146.             PrCloseDoc(prPort);
  147.             if (sts=PrError()) { sprintf(tmp,"PrCloseDoc: ERROR %d",sts); putln(tmp); }
  148.             if (((*PrRecHandle)->prJob.bJDocLoop == bSpoolLoop) && (PrError()==0)) {
  149.                 PrPicFile(PrRecHandle,0L,0L,0L,&prStatus); /* Spool if necessary… */
  150.                 if (sts=PrError()) { sprintf(tmp,"PrPicFile: ERROR %d",sts); putln(tmp); }
  151.             }
  152.         }
  153.     }
  154.     
  155.     PrClose();
  156.     DisposeHandle((Handle)PrRecHandle);
  157.     
  158.     SetPort (savePort);                /* restore old port */
  159.     if (sts=FSClose (VSIw->refNum)) {
  160.         SysBeep(1);
  161.         sprintf(tmp,"FSClose: ERROR %d",sts); putln(tmp);
  162.     }
  163.     VSIw->refNum = -1;
  164.  
  165.     if (sts=HDelete(TempItemsVRefNum, TempItemsDirID, (StringPtr)VSIw->fname)) {
  166.         SysBeep(1);
  167.         sprintf(tmp,"HDelete: ERROR %d",sts); putln(tmp);
  168.     }
  169.     updateCursor(1);
  170. }
  171.  
  172.  
  173. #define ENDOFPRT     '\033[4i'        /* <ESC>[4i   (0x1b5b3469) */
  174.  
  175. void VSpr(unsigned char **pc, short *pctr)
  176. {
  177.     long count;                /* number of chars to print to file */
  178.     char *start;             /* original start of buffer */
  179.     OSErr sts;
  180.     char tmp[100];            /* only for debugging */
  181.     short rdy;                /* true if <ESC>[4i */
  182.  
  183.     count=0;                
  184.     start=(char *)*pc;    
  185.     rdy=0;
  186.  
  187.     while ((*pctr>0) && (!rdy)) {
  188.         VSIw->prbuf=(VSIw->prbuf<<8) + **pc;
  189.         if (VSIw->prbuf==ENDOFPRT) {            /* i.e. no more redirection */
  190.             rdy=1;
  191.             count--;                    /* will be incremented again below */
  192.         }
  193.         count++;
  194.         (*pc)++;
  195.         (*pctr)--;
  196.     }
  197.  
  198.     trbuf_nat_mac ((unsigned char *)start,count, screens[findbyVS(VSIwn)].national);
  199.     if (sts=FSWrite(VSIw->refNum,&count,start)) {
  200.         SysBeep(1);
  201.         sprintf(tmp,"FSWrite: ERROR %d",sts); putln(tmp);
  202.     }
  203.     if (rdy || sts)
  204.         VSprOFF();
  205. }
  206.  
  207.  
  208.  
  209. /* LU - that is the end of the new routines needed for printer redirection     */
  210. /* LU - now we just patch up VSem() to use this code, and were done!         */
  211.  
  212.  
  213.  
  214.  
  215.  
  216.  
  217.  
  218. void VSem
  219.   (
  220.     unsigned char *c, /* pointer to character string */
  221.     short ctr /* length of character string */
  222.   )
  223.   /* basic routine for placing characters on a virtual screen, and
  224.     interpreting control characters and escape sequences. Simple
  225.     interpretation of controls & escapes is done here, while the
  226.     harder stuff is done by calling VSIxx routines in vsintern.c. */
  227. {
  228.     register short sx;
  229.     register short escflg; /* state of escape sequence interpretation */
  230.     short insert, attrib, extra, offend;
  231.     char *acurrent, *current, *start;
  232.  
  233.     escflg = VSIw->escflg;
  234.  
  235.     while (ctr > 0)
  236.       {
  237.         if (VSIw->prredirect)    /* PR - printer redirection? */
  238.         VSpr(&c,&ctr);            /* PR -if yes, call VSpr */
  239.                                 /* PR - when we return from VSpr there may (ctr!=0) … */
  240.                                 /* PR - … or may not (ctr==0) be chars left in *c to print */
  241.         while ((escflg == 0) && (ctr > 0) && (*c < 32))
  242.           {
  243.             switch (*c)
  244.               {
  245.                 case 0x1b: /* esc */
  246.                     escflg++;
  247.                     break;
  248.                 case 0x0e: /* shift out */
  249.                     if (VSIw->G1)
  250.                         VSIw->attrib = VSgraph(VSIw->attrib);
  251.                     else
  252.                         VSIw->attrib = VSnotgraph(VSIw->attrib);
  253.                     VSIw->charset = 1;
  254.                     break;
  255.                 case 0x0f: /* shift in */
  256.                     if (VSIw->G0)
  257.                         VSIw->attrib = VSgraph(VSIw->attrib);
  258.                     else
  259.                         VSIw->attrib = VSnotgraph(VSIw->attrib);
  260.                     VSIw->charset = 0;
  261.                     break;
  262.                 case 0x07: /* bell */
  263.                     RSbell(VSIwn);
  264.                     break;
  265.                 case 0x08: /* backspace */
  266.                     VSIw->x--;
  267.                     if (VSIw->x < 0)
  268.                       /* hit left margin */
  269.                         VSIw->x = 0;
  270.                     break;
  271.                 case 0x0c: /* ff */
  272.                     VSIindex();
  273.                     break;
  274.                 case 0x09: /* ht */        /* Later change for versatile tabbing */
  275.                     VSItab();
  276.                     VScapture(c,1);                /* BYU 2.4.18 */
  277.                     break;
  278.                 case 0x0a: /* lf */
  279.                     VSIindex();
  280.                     break;
  281.                 case 0x0d: /* cr */
  282.                     VSIw->x = 0;
  283.                     VScapture(c,1);                /* BYU 2.4.18 */
  284.                     break;
  285.                 case 0x0b: /* vt */
  286.                     VSIindex();
  287.                     break;
  288. #ifdef CISB
  289.                 case 0x10: /* dle */
  290.                     bp_DLE(c, ctr);
  291.                     ctr = 0;
  292.                     break;
  293.                 case 0x05: /* enq */
  294.                     bp_ENQ();
  295.                     break;
  296. #endif CISB
  297.               } /* switch */
  298.             c++;
  299.             ctr--;
  300.           } /* while */
  301.         if ((escflg == 0) && (ctr > 0) && (*c & 0x80) && (*c < 0xA0)
  302.             && (screens[findbyVS(VSIwn)].vtemulation == 1))    /* BYU 2.4.12 - VT220 starts here */
  303.           {                                                /* BYU 2.4.12 */
  304.             switch (*c)                                    /* BYU 2.4.12 */
  305.               {                                            /* BYU 2.4.12 */
  306.                 case 0x84: /* ind */            /* BYU 2.4.12 - same as ESC D */
  307.                     VSIindex();                    /* BYU 2.4.12 */
  308.                     goto ShortCut;                /* BYU 2.4.12 */
  309.                 case 0x85: /* nel */            /* BYU 2.4.12 - same as ESC E */
  310.                     VSIw->x = 0;                /* BYU 2.4.12 */
  311.                     VSIindex();                    /* BYU 2.4.12 */
  312.                     goto ShortCut;                /* BYU 2.4.12 */
  313.                 case 0x88: /* hts */            /* BYU 2.4.12 - same as ESC H */
  314.                     VSIw->tabs[VSIw->x] = 'x';    /* BYU 2.4.12 */
  315.                     goto ShortCut;                /* BYU 2.4.12 */
  316.                 case 0x8d: /* ri */                /* BYU 2.4.12 - same as ESC M */
  317.                     VSIrindex();                /* BYU 2.4.12 */
  318.                     goto ShortCut;                /* BYU 2.4.12 */
  319.                 case 0x9b: /* csi */            /* BYU 2.4.12 - same as ESC [ */
  320.                     VSIapclear();                /* BYU 2.4.12 */
  321.                     escflg = 2;                    /* BYU 2.4.12 */
  322.                     break;                        /* BYU 2.4.12 */
  323.                 case 0x86: /* ssa */            /* BYU 2.4.12 - same as ESC F */
  324.                 case 0x87: /* esa */            /* BYU 2.4.12 - same as ESC G */
  325.                 case 0x8e: /* ss2 */            /* BYU 2.4.12 - same as ESC N */
  326.                 case 0x8f: /* ss3 */            /* BYU 2.4.12 - same as ESC O */
  327.                 case 0x90: /* dcs */            /* BYU 2.4.12 - same as ESC P */
  328.                 case 0x93: /* sts */            /* BYU 2.4.12 - same as ESC S */
  329.                 case 0x96: /* spa */            /* BYU 2.4.12 - same as ESC V */
  330.                 case 0x97: /* epa */            /* BYU 2.4.12 - same as ESC W */
  331.                 case 0x9d: /* osc */            /* BYU 2.4.12 - same as ESC ] */
  332.                 case 0x9e: /* pm */                /* BYU 2.4.12 - same as ESC ^ */
  333.                 case 0x9f: /* apc */            /* BYU 2.4.12 - same as ESC _ */
  334.                     goto ShortCut;                /* BYU 2.4.12 */
  335.               } /* switch */                    /* BYU 2.4.12 */
  336. /*
  337.  * Not sure why this code was here. It causes Telnet to ignore printable chars
  338.  * >= 0x80. RW. 5/27/93
  339.  */
  340. #ifdef notdef
  341.             c++;                                /* BYU 2.4.12 */
  342.             ctr--;                                /* BYU 2.4.12 */
  343. #endif
  344.           } /* if */                            /* BYU 2.4.12 */
  345.         while ((ctr > 0) && (escflg == 0) && (*c >= 32))
  346.           {
  347.           /* display printing characters */
  348.             start = &VSIw->linest[VSIw->y]->text[VSIw->x]; /* start of area needing redrawing */
  349.             current = start; /* where to put next char */
  350.             acurrent = &VSIw->attrst[VSIw->y]->text[VSIw->x]; /* where to put corresponding attribute byte */
  351.             attrib = VSIw->attrib; /* current writing attribute */
  352.             insert = VSIw->IRM; /* insert mode (boolean) */
  353.             offend = 0; /* wrapped to next line (boolean) */
  354.             extra = 0; /* overwriting last character of line (boolean) */
  355.             sx = VSIw->x; /* starting column of area needing redrawing */
  356.             if (VSIw->x > VSIw->maxwidth)
  357.               {
  358.                 if (VSIw->DECAWM)
  359.                   {
  360.                   /* wrap to next line */
  361.                     VSIw->x = 0;
  362.                     VSIindex();
  363.                   }
  364.                 else
  365.                   /* stay at right margin */
  366.                     VSIw->x = VSIw->maxwidth;
  367.                 current = start = &VSIw->linest[VSIw->y]->text[VSIw->x];
  368.                 acurrent = &VSIw->attrst[VSIw->y]->text[VSIw->x];
  369.                 sx = VSIw->x;
  370.               } /* if */
  371.             while ((ctr > 0) && (*c >= 32) && (offend == 0))
  372.               {
  373.               trbuf_nat_mac(c,1, screens[findbyVS(VSIwn)].national);            /* LU/MP: translate to national chars */
  374.               /* write characters within a single line */
  375.                 if (insert)
  376.                   /* make room for the char */
  377.                     VSIinschar(1);
  378.               /* poke the character and its attribute into the
  379.                 screen buffer at the current cursor position */
  380.                 *current = *c;
  381.                 *acurrent = attrib;
  382.                 c++;
  383.                 ctr--;
  384.                 if (VSIw->x < VSIw->maxwidth)
  385.                   {
  386.                   /* advance the cursor position */
  387.                     acurrent++;
  388.                     current++;
  389.                     VSIw->x++;
  390.                   }
  391.                 else
  392.                   {
  393.                   /* hit right margin */
  394.                     if (VSIw->DECAWM)
  395.                       {
  396.                       /* autowrap to start of next line */
  397.                         VSIw->x++;
  398.                         offend = 1; /* terminate inner loop */
  399.                       }
  400.                     else
  401.                       {
  402.                       /* stay at right margin */
  403.                         VSIw->x = VSIw->maxwidth;
  404.                         extra = 1; /* cursor position doesn't advance */
  405.                       } /* if */
  406.                   } /* if */
  407.               } /* while */
  408.           /* update the screen to show what I've done */
  409.               extra += VSIw->x - sx + offend;                                    /* BYU 2.4.18 */
  410.             if (insert)
  411.                 VSIinsstring(extra, start);                                    /* BYU 2.4.18 */
  412.                                     /* actually just decides which RS to use */
  413.             else
  414.                 VSIdraw(VSIwn, sx, VSIw->y, VSIw->attrib, extra, start);    /* BYU 2.4.18 */
  415.             VScapture((unsigned char *) start, extra);                        /* BYU 2.4.18 */
  416.           } /* while */
  417.  
  418.         while((ctr > 0) && (escflg == 1))
  419.           { /* basic escape sequence processing */
  420.             switch (*c)
  421.               {
  422.                 case 0x08:
  423.                     VSIw->x--;
  424.                     if (VSIw->x < 0)
  425.                         VSIw->x = 0;
  426.                     break;
  427.                 case '[': /* csi */
  428.                     VSIapclear();
  429.                     escflg++;
  430.                     break;
  431.                 case '7':
  432.                     VSIsave();
  433.                     goto ShortCut;                /* BYU 2.4.12 */
  434.                 case '8':
  435.                     VSIrestore();
  436.                     goto ShortCut;                /* BYU 2.4.12 */
  437.                 case 'c':
  438.                     VSIreset();
  439.                     break;
  440.                 case 'D':
  441.                     VSIindex();
  442.                     goto ShortCut;                /* BYU 2.4.12 */
  443.                 case 'E':
  444.                     VSIw->x = 0;
  445.                     VSIindex();
  446.                     goto ShortCut;                /* BYU 2.4.12 */
  447.                 case 'M':
  448.                     VSIrindex();
  449.                     goto ShortCut;                /* BYU 2.4.12 */
  450.                 case '>':
  451.                     VSIw->DECPAM = 0;
  452.                     goto ShortCut;                /* BYU 2.4.12 */
  453.                 case '=':
  454.                     VSIw->DECPAM = 1;
  455.                     goto ShortCut;                /* BYU 2.4.12 */
  456.                 case 'Z':
  457.                     VTsendident();
  458.                     goto ShortCut;                /* BYU 2.4.12 */
  459.                 case ' ':                        /* BYU 2.4.12 */
  460.                 case '*':                        /* BYU 2.4.12 */
  461.                 case '#':
  462.                     escflg = 3;
  463.                     break;
  464.                 case '(':
  465.                     escflg = 4;
  466.                     break;
  467.                 case ')':
  468.                     escflg = 5;
  469.                     break;
  470.                 case 'H':
  471.                     VSIw->tabs[VSIw->x] = 'x';
  472.                     goto ShortCut;                /* BYU 2.4.12 */
  473. #ifdef CISB
  474.                 case 'I':
  475.                     bp_ESC_I();
  476.                     break;
  477. #endif CISB
  478.                 case ']':                                // WNR - XTerm
  479.                     if (screens[findbyVS(VSIwn)].Xterm)    // WNR - XTerm
  480.                         escflg = 6;                        // WNR - XTerm
  481.                     break;                                // WNR - XTerm
  482.                     
  483.                 default:
  484.                     goto ShortCut;                /* BYU 2.4.12 */
  485.               } /* switch */
  486.             c++;
  487.             ctr--;
  488.           } /* while */
  489.         while ((escflg == 2) && (ctr > 0))
  490.           { /* "control sequence" processing */
  491.             switch (*c)
  492.               {
  493.                 case 0x08:
  494.                     VSIw->x--;
  495.                     if (VSIw->x < 0)
  496.                         VSIw->x = 0;
  497.                     break;
  498.                 case '0':
  499.                 case '1':
  500.                 case '2':
  501.                 case '3':
  502.                 case '4':
  503.                 case '5':
  504.                 case '6':
  505.                 case '7':
  506.                 case '8':
  507.                 case '9':
  508.                   /* parse numeric parameter */
  509.                     if (VSIw->parms[VSIw->parmptr] < 0)
  510.                         VSIw->parms[VSIw->parmptr] = 0;
  511. #if 0 /* MPW code generator bug */
  512.                     VSIw->parms[VSIw->parmptr] *= 10;
  513. #else
  514.                     VSIw->parms[VSIw->parmptr] = VSIw->parms[VSIw->parmptr] * 10;
  515. #endif
  516.                     VSIw->parms[VSIw->parmptr] += *c - '0';
  517.                     break;
  518.                 case '?':
  519.                   /* DEC-private control sequence */
  520.                     VSIw->parms[VSIw->parmptr++] = -2;
  521.                     break;
  522.                 case ';':
  523.                   /* parameter separator */
  524.                     VSIw->parmptr++;
  525.                     break;
  526.                 case 'A': /* cursor up */
  527. #if 1                                                        /* BYU */
  528.                     if (VSIw->parms[0]<1) VSIw->y--;        /* BYU */
  529.                     else VSIw->y-=VSIw->parms[0];            /* BYU */
  530.                     if ( VSIw->y < 0 ) VSIw->y=0;            /* BYU */
  531.                     if (VSIw->y < VSIw->top)                /* NCSA: SB */
  532.                         VSIw->y = VSIw->top;                /* NCSA: SB */
  533.                         
  534. #else                                                        /* BYU */
  535.                     if (VSIw->y < VSIw->top)
  536.                       {
  537.                       /* outside scrolling region */
  538.                         if (VSIw->parms[0] < 1)
  539.                             VSIw->y--;
  540.                         else
  541.                             VSIw->y -= VSIw->parms[0];
  542.                       }
  543.                     else
  544.                       {
  545.                       /* don't leave scrolling region */
  546.                         if (VSIw->parms[0] < 1)
  547.                             VSIw->y--;
  548.                         else
  549.                             VSIw->y -= VSIw->parms[0];
  550.                         if (VSIw->y < VSIw->top)
  551.                             VSIw->y = VSIw->top;
  552.                       }
  553. #endif                                                        /* BYU */
  554.                     VSIrange();
  555.                     goto ShortCut;                /* BYU 2.4.12 */
  556.                 case 'B': /* cursor down */
  557. #if 1                                                        /* BYU */
  558.                     if (VSIw->parms[0]<1) VSIw->y++;        /* BYU */
  559.                     else VSIw->y+=VSIw->parms[0];            /* BYU */
  560.                     if (VSIw->y > VSIw->bottom)                /* NCSA: SB */
  561.                         VSIw->y = VSIw->bottom;                /* NCSA: SB */
  562.                         
  563. #else                                                        /* BYU */
  564.                     if (VSIw->y > VSIw->bottom)
  565.                       {
  566.                       /* outside scrolling region */
  567.                         if (VSIw->parms[0] < 1)
  568.                             VSIw->y++;
  569.                         else
  570.                             VSIw->y += VSIw->parms[0];
  571.                       }
  572.                     else
  573.                       {
  574.                       /* don't leave scrolling region */
  575.                         if (VSIw->parms[0] < 1)
  576.                             VSIw->y++;
  577.                         else
  578.                             VSIw->y += VSIw->parms[0];
  579.                         if (VSIw->y > VSIw->bottom)
  580.                             VSIw->y = VSIw->bottom;
  581.                       }
  582. #endif                                                        /* BYU */
  583.                     VSIrange();
  584.                     goto ShortCut;                /* BYU 2.4.12 */
  585.                 case 'C': /* cursor right */
  586.                     if (VSIw->parms[0] < 1)
  587.                         VSIw->x++;
  588.                     else
  589.                         VSIw->x += VSIw->parms[0];
  590.                     VSIrange();
  591.                     if (VSIw->x > VSIw->maxwidth)
  592.                         VSIw->x = VSIw->maxwidth;
  593.                     goto ShortCut;                /* BYU 2.4.12 */
  594.                 case 'D': /* cursor left */
  595.                     if (VSIw->parms[0] < 1)
  596.                         VSIw->x--;
  597.                     else
  598.                         VSIw->x -= VSIw->parms[0];
  599.                     VSIrange();
  600.                     goto ShortCut;                /* BYU 2.4.12 */
  601.                 case 'f':
  602.                 case 'H':
  603.                   /* absolute cursor positioning */
  604.                     VSIw->x = VSIw->parms[1] - 1;
  605.                     if (VSIw->DECORG)
  606.                       /* origin mode -- position relative to top of scrolling region */
  607.                         VSIw->y = VSIw->parms[0] - 1 + VSIw->top;
  608.                     else
  609.                         VSIw->y = VSIw->parms[0] - 1;
  610.                     /*    Don't use actual VSIrange 'cause it will wrap us to first column if 
  611.                         we are past screen edge.  This causes "resize" to break */
  612.                     if (VSIw->x < 0)                        /* JMB 2.6 */
  613.                         VSIw->x = 0;                        /* JMB 2.6 */
  614.                     if (VSIw->x > (VSIw->maxwidth))            /* JMB 2.6 */
  615.                         VSIw->x = VSIw->maxwidth;            /* JMB 2.6 */
  616.                     if (VSIw->y < 0)                        /* JMB 2.6 */
  617.                         VSIw->y = 0;                        /* JMB 2.6 */
  618.                     if (VSIw->y > VSIw->lines)                /* JMB 2.6 */
  619.                         VSIw->y = VSIw->lines;                /* JMB 2.6 */
  620.                     goto ShortCut;                /* BYU 2.4.12 */
  621.                 case 'i':                                            /* PR: media copy */
  622.                     if (VSIw->parms[VSIw->parmptr]==5) {            /* PR */
  623.                         /*c++; ctr--; */                            /* PR */            
  624.                         VSprON();    /* PR - set status and open temp file etc */
  625.                                     /* PR - chars will be redirected at top of loop … */
  626.                                     /* PR - … in this procedure */
  627.                     }                /* PR */
  628.                     escflg = 0;        /* PR */
  629.                     break;            /* PR */
  630.                 case 'K':
  631.                   /* erase to beginning/end/whole of line */
  632.                     switch (VSIw->parms[0])
  633.                       {
  634.                         case -1:
  635.                         case  0:
  636.                             VSIeeol();
  637.                             break;
  638.                         case  1:
  639.                             VSIebol();
  640.                             break;
  641.                         case  2:
  642.                             VSIel(-1);
  643.                             break;
  644.                         default:
  645.                             goto ShortCut;        /* BYU 2.4.12 */
  646.                       } /* switch */
  647.                     goto ShortCut;                /* BYU 2.4.12 */
  648.                 case 'J':
  649.                   /* erase to beginning/end/whole of screen */
  650.                     switch (VSIw->parms[0])
  651.                       {
  652.                         case -1:
  653.                         case  0:
  654.                             VSIeeos();
  655.                             break;
  656.                         case  1:
  657.                             VSIebos();
  658.                             break;
  659.                         case  2:
  660.                             VSIes();
  661.                             break;
  662.                         default:
  663.                             goto ShortCut;        /* BYU 2.4.12 */
  664.                       } /* switch */
  665.                     goto ShortCut;                /* BYU 2.4.12 */
  666.                 case 'm':
  667.                   /* set/clear attributes */
  668.                   {
  669.                     short temp = 0;
  670.                     while (temp <= VSIw->parmptr)
  671.                       {
  672.                         if (VSIw->parms[temp] < 1)
  673.                             VSIw->attrib &= 128; /* turn them all off */
  674.                         else if (VSIw->parms[temp] > 20)                        /* BYU 2.4.13 */
  675.                           /* turn off the appropriate bit */                    /* BYU 2.4.13 */
  676.                             VSIw->attrib &= ~(1 << (VSIw->parms[temp] - 21));    /* BYU 2.4.13 */
  677.                         else
  678.                           /* turn on the appropriate bit */
  679.                             VSIw->attrib |= 1 << (VSIw->parms[temp] - 1);
  680.                         temp++;
  681.                       } /* while */
  682.                   }
  683.                   goto ShortCut;                /* BYU 2.4.12 */
  684.                 case 'q':
  685.                   /* flash dem LEDs. What LEDs? */
  686.                     goto ShortCut;                /* BYU 2.4.12 */
  687.                 case 'c':
  688.                     VTsendident();
  689.                     goto ShortCut;                /* BYU 2.4.12 */
  690.                 case 'n':
  691.                     switch (VSIw->parms[0])
  692.                       {
  693.                         case 5:
  694.                             VTsendstat();
  695.                             break;
  696.                         case 6:
  697.                             VTsendpos();
  698.                             break;
  699.                       } /* switch */
  700.                     goto ShortCut;                /* BYU 2.4.12 */
  701.                 case 'L':
  702.                     if (VSIw->parms[0] < 1)
  703.                         VSIw->parms[0] = 1;
  704.                     VSIinslines(VSIw->parms[0], -1);
  705.                     goto ShortCut;                /* BYU 2.4.12 */
  706.                 case 'M':
  707.                     if (VSIw->parms[0] < 1)
  708.                         VSIw->parms[0] = 1;
  709.                     VSIdellines(VSIw->parms[0], -1);
  710.                     goto ShortCut;                /* BYU 2.4.12 */
  711.                 case 'P':
  712.                     if (VSIw->parms[0] < 1)
  713.                         VSIw->parms[0] = 1;
  714.                     VSIdelchars(VSIw->parms[0]);
  715.                     goto ShortCut;                /* BYU 2.4.12 */
  716.                 case 'r':
  717.                   /* set scrolling region */
  718.                     if (VSIw->parms[0] < 0)
  719.                         VSIw->top = 0;
  720.                     else
  721.                         VSIw->top = VSIw->parms[0] - 1;
  722.                     if (VSIw->parms[1] < 0)
  723.                         VSIw->bottom = VSIw->lines;
  724.                     else
  725.                         VSIw->bottom = VSIw->parms[1] - 1;
  726.                     if (VSIw->top < 0)
  727.                         VSIw->top = 0;
  728.                     if (VSIw->top > VSIw->lines - 1)
  729.                         VSIw->top = VSIw->lines - 1;
  730.                     if (VSIw->bottom < 1)
  731.                         VSIw->bottom = VSIw->lines;
  732.                     if (VSIw->bottom > VSIw->lines)
  733.                         VSIw->bottom = VSIw->lines;
  734.  
  735.                     if (VSIw->top >= VSIw->bottom)            /* NCSA: SB */
  736.                         {                                    /* NCSA: SB */
  737.                         if (VSIw->bottom >=1)                /* NCSA: SB */
  738.                             VSIw->top = VSIw->bottom -1;    /* NCSA: SB */
  739.                         else VSIw->bottom = VSIw->top +1;    /* NCSA: SB */
  740.                         }                                    /* NCSA: SB */
  741.                  
  742.                      VSIw->x = 0;
  743.                     VSIw->y = 0;
  744.                     if (VSIw->DECORG)
  745.                         VSIw->y = VSIw->top;    /* origin mode relative */
  746.                     goto ShortCut;                /* BYU 2.4.12 */
  747.                 case 'h':
  748.                   /* set options */
  749.                     VSIsetoption(1);
  750.                     goto ShortCut;                /* BYU 2.4.12 */
  751.                 case 'l':
  752.                   /* reset options */
  753.                     VSIsetoption(0);
  754.                     goto ShortCut;                /* BYU 2.4.12 */
  755.                 case 'g':
  756.                     if (VSIw->parms[0] == 3)
  757.                       /* clear all tabs */
  758.                         VSItabclear();
  759.                     else if (VSIw->parms[0] <= 0)
  760.                       /* clear tab at current position */
  761.                         VSIw->tabs[VSIw->x] = ' ';
  762.                     goto ShortCut;                /* BYU 2.4.12 */
  763.                 case '!':                        /* BYU 2.4.12 - More private DEC stuff? */
  764.                 case '\'':                        /* BYU 2.4.12 - More private DEC stuff? */
  765.                 case '\"':                        /* BYU 2.4.12 - More private DEC stuff? */
  766.                     escflg++;                    /* BYU 2.4.12 */
  767.                     break;                        /* BYU 2.4.12 */
  768.                 default:            /* Dang blasted strays... */
  769.                     goto ShortCut;                /* BYU 2.4.12 */
  770.               } /* switch */
  771.             c++;
  772.             ctr--;
  773.           } /* while */
  774.  
  775.         while ((escflg == 3) && (ctr > 0))
  776.           {    /* "#" handling */
  777.           /* no support for double-width and double-height characters yet */
  778.             switch (*c)
  779.               {
  780.                 case 0x08:
  781.                     VSIw->x--;
  782.                     if (VSIw->x < 0)
  783.                         VSIw->x = 0;
  784.                     break;
  785.                 case '8': /* alignment display */
  786.                     VTalign();
  787.                     goto ShortCut;                /* BYU 2.4.12 */
  788.                 default:
  789.                     goto ShortCut;                /* BYU 2.4.12 */
  790.               } /* switch */
  791.             c++;
  792.             ctr--;
  793.           } /* while */
  794.  
  795.         while ((escflg == 4) && (ctr > 0))
  796.           {    /* "(" handling (selection of G0 character set) */
  797.             switch (*c)
  798.               {
  799.                 case 0x08:
  800.                     VSIw->x--;
  801.                     if (VSIw->x < 0)
  802.                         VSIw->x = 0;
  803.                     break;
  804.                 case 'A': /* UK */
  805.                 case 'B': /* US */
  806.                 case '1': /* "soft" */
  807.                     VSIw->G0 = 0;
  808.                     if (!VSIw->charset)
  809.                         VSIw->attrib = VSnotgraph(VSIw->attrib);
  810.                     goto ShortCut;                /* BYU 2.4.12 */
  811.                 case '0': /* DEC special graphics */
  812.                 case '2': /* "soft" */
  813.                     VSIw->G0 = 1;
  814.                     if (!VSIw->charset)
  815.                         VSIw->attrib = VSgraph(VSIw->attrib);
  816.                     goto ShortCut;                /* BYU 2.4.12 */
  817.                 default:
  818.                     goto ShortCut;                /* BYU 2.4.12 */
  819.               } /* switch */
  820.             c++;
  821.             ctr--;
  822.           } /* while */
  823.     
  824.         while ((escflg == 5) && (ctr > 0))
  825.           {    /* ")" handling (selection of G1 character set) */
  826.             switch (*c)
  827.               {
  828.                 case 0x08:
  829.                     VSIw->x--;
  830.                     if (VSIw->x < 0)
  831.                         VSIw->x = 0;
  832.                     break;
  833.                 case 'A': /* UK */
  834.                 case 'B': /* US */
  835.                 case '1': /* "soft" */
  836.                     VSIw->G1 = 0;
  837.                     if (VSIw->charset)
  838.                         VSIw->attrib = VSnotgraph(VSIw->attrib);
  839.                     goto ShortCut;                /* BYU 2.4.12 */
  840.                 case '0': /* DEC special graphics */
  841.                 case '2': /* "soft" */
  842.                     VSIw->G1 = 1;
  843.                     if (VSIw->charset)
  844.                         VSIw->attrib = VSgraph(VSIw->attrib);
  845.                     goto ShortCut;                /* BYU 2.4.12 */
  846.                 default:
  847.                     goto ShortCut;                /* BYU 2.4.12 */
  848.               } /* switch */
  849.             c++;
  850.             ctr--;
  851.           } /* while */
  852.  
  853.         // Handle XTerm rename functions, code contributed by Bill Rausch
  854.         // Modified by JMB to handle ESC]2; case as well.
  855.         if( (escflg >= 6) && (ctr > 0) ) {
  856.             static char *tmp;
  857.             static Str255 newname;
  858.           
  859.         if( (escflg == 6) && ((*c == '0') || (*c == '2'))) {
  860.             escflg++;
  861.             c++;
  862.             ctr--;
  863.             }
  864.         if( (escflg == 7 ) && (ctr > 0) && (*c == ';') ) {
  865.             ctr--;
  866.             c++;
  867.             escflg++;
  868.             newname[0] = 0;
  869.             tmp = (char *)&newname[1];
  870.             }
  871.         while( (escflg == 8) && (ctr > 0) && (*c != 07) ) {
  872.             *tmp++ = *c++;
  873.             ctr--;
  874.             (*newname)++;
  875.             }
  876.         if( (escflg == 8) && (*c == 07) && (ctr > 0) ) {
  877.             set_new_window_name( newname, RSgetwindow(VSIwn) );
  878.             goto ShortCut;
  879.             }
  880.         } /* if */
  881.  
  882.         if ((escflg > 2) && (ctr > 0))
  883.           {
  884. ShortCut:                        /* BYU 2.4.12 - well, sacrificing style for speed */
  885.             escflg = 0;
  886.             c++;
  887.             ctr--;
  888.           } /* if */
  889.       } /* while (ctr > 0) */
  890.     VSIw->escflg = escflg;
  891.   } /* VSem */
  892.  
  893.